<?php

namespace Lib;

use Lib\Base\Request;
use Lib\Base\Response;
use Lib\UlinkMain;

class App
{
    /**
     * 应用程序入口
     */
    public static function run()
    {
        //设置请求头跨域
        if (defined('ENV') && ENV == 'test' && isset($_SERVER['HTTP_ORIGIN'])) {
            header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
            header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
            header('Access-Control-Allow-Credentials: true');
        }

        //内部开发时直接通过url测试接口，生成一个流水号，方便查看日志
        if (RUN_ENV == 'internal') {

            if (defined('PAAS_INSTANCE_ID') && !empty(PAAS_INSTANCE_ID)) {
                $activityId = PAAS_INSTANCE_ID;
            } else if (!empty(Request::param('iAmsActivityId'))) {
                $activityId = Request::param('iAmsActivityId');
            } else {
                $activityId = '281592';
            }

            if (defined('S_SERVICE_TYPE') && !empty(S_SERVICE_TYPE)) {
                $sServiceType = S_SERVICE_TYPE;
            } else if (!empty(Request::param('sServiceType'))) {
                $sServiceType = Request::param('sServiceType');
            } else {
                $sServiceType = 'internal';
            }

            if (empty(Request::param('sAmsSerial'))) {
                Request::setGetParam('sAmsSerial', createAmsSerial($activityId, strtoupper($sServiceType)));
            }
        }

        global $NTX_LOGGER;
        if (RUN_ENV == 'internal' || (defined('ENV') && ENV != 'test')) {
            $NTX_LOGGER = new \Logger(null);
        }

        if (php_sapi_name() != 'cli') {
            $route = Request::param('route');
            if (empty($route) || substr_count($route, '/') != 1) {
                $module = Request::param('c'); //controller
                $action = Request::param('a'); //method
            } else {
                $arr = explode('/', $route);
                $module = $arr[0];
                $action = $arr[1];
            }
        } else {
            $module = Request::param('c');
            if ($module === '') {
                $module = Request::param('1');
            }
            $action = Request::param('a');
            if ($action === '') {
                $action = Request::param('2');
            }
        }

        if ($module == '') {
            echo Response::outputJson(array('iRet' => '-100500', 'sMsg' => 'no ctrl'));
            exit;
        }
        if ($action == '') {
            echo Response::outputJson(array('iRet' => '-100501', 'sMsg' => 'no action'));
            exit;
        }

        $module .= 'Ctrl';
        $className = 'Ctrl\\' . $module;
        if (RUN_ENV == 'ulink') {
            UlinkMain::init($module . '/' . $action); //ulink 流程初始化
        }

        if (RUN_ENV == 'internal') {
            recordLog('php_sapi_name=' . php_sapi_name(), __FILE__, __LINE__);

            if (php_sapi_name() != 'cli') {
                //get log
                recordLog('$_GET=' . var_export(Request::getParam(), true), __FILE__, __LINE__);

                //post log
                recordLog('$_POST=' . var_export(Request::postParam(), true), __FILE__, __LINE__);

                //cookie log
                recordLog('$_COOKIE=' . var_export(Request::cookieParam(), true), __FILE__, __LINE__);

                //server log
                recordLog('$_SERVER=' . var_export(Request::serverParam(), true), __FILE__, __LINE__);
            }
        }


        try {
            //讲请求路由到对应的模块
            if (class_exists('ReflectionClass') && class_exists('ReflectionMethod')) {
                $reflectionObj = new \ReflectionClass($className);
                $moduleObj = $reflectionObj->newInstance();

                $reflectionMethod = new \ReflectionMethod($className, $action);

                if ($reflectionMethod->isPublic() || $reflectionMethod->isStatic()) {
                    $reflectionMethod->invoke($moduleObj, 0);
                } else {
                    throw new \Exception("$className:$action 是private方法，对外无法调用，请修改！", -1001);
                }
            } else {
                $obj = new $className();
                $obj->$action();
            }
        } catch (\Exception $e) {
            recordLog('自动加载失败，错误信息：' . $e->getMessage(), __FILE__, __LINE__, LP_ERROR);
            echo Response::outputJson(array('iRet' => '-100008', 'sMsg' => 'ctrl or action not find!'));
            exit;
        }
    }
}
